﻿using AnQinFrameWorkAPI.Common.Enum;
using AnQinFrameWorkAPI.DataBase;
using AnQinFrameWorkAPI.Entity.SystemCore.DTO.CodeRule;
using AnQinFrameWorkAPI.Entity.SystemCore.Entity;
using AnQinFrameWorkAPI.Entity.SystemCore.View.CodeRule;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using FrameWork.DataHelper;
using FrameWork.Entity;
using FrameWork.Request;
using Microsoft.EntityFrameworkCore;

namespace AnQinFrameWorkAPI.Service.SystemCore;

/// <summary>
///     编码规则业务层
/// </summary>
public class CodeRuleService
{
    #region 获取编码规则列表

    public async Task<RequestResponseModel> GetCodeRuleList(CodeRuleSearchDTO codeRuleSearchDTO)
    {
        //筛选
        var query = _context.CodeRule
                .ProjectTo<CodeRuleView>(_mapper.ConfigurationProvider)
                .AsNoTracking()
                .WhereIF(a => a.Name.Contains(codeRuleSearchDTO.Name),
                    !string.IsNullOrEmpty(codeRuleSearchDTO.Name))
            ;

        //返回列表
        var codeRuleList = await query
            .OrderBy(a => a.Order)
            .Page(codeRuleSearchDTO.PageIndex, codeRuleSearchDTO.PageSize)
            .ToListAsync();

        //总数据量
        var pageCount = await query.CountAsync();

        //返回数据
        var pageResult = new PageResult<CodeRuleView>(codeRuleList, pageCount);
        return RequestResponse.OK(pageResult, "查询成功");
    }

    #endregion

    #region 新增编码规则

    public async Task<RequestResponseModel> AddCodeRule(CodeRuleAddDTO codeRuleAddDTO)
    {
        //处理主单
        var codeRule = _mapper.Map<CodeRuleModel>(codeRuleAddDTO);
        codeRule.Id = Guid.NewGuid();
        codeRule.CreateTime = DateTime.Now;

        //处理子单
        var codeRuleItem = _mapper.Map<List<CodeRuleItemModel>>(codeRuleAddDTO.Items);
        foreach (var item in codeRuleItem)
        {
            item.Id = Guid.NewGuid();
            item.CodeRuleId = codeRule.Id;

            if (item.CodeType == SystemCoreEnum.CodeTypeEnum.流水号) item.CurrentSerialNumber = 0;
        }

        //新增数据
        _context.CodeRule.Add(codeRule);
        _context.CodeRuleItem.AddRange(codeRuleItem);
        await _context.SaveChangesAsync();

        return RequestResponse.OK(codeRule.Id, "新增成功");
    }

    #endregion

    #region 更新编码规则

    public async Task<RequestResponseModel> PutCodeRule(CodeRuleUpdateDTO codeRuleUpdateDTO)
    {
        //处理主单
        var query = await Valid.ValidId(_context.CodeRule, codeRuleUpdateDTO.Id);
        if (query == null) return RequestResponse.ErrorRequest("编码规则Id无效");

        //处理子单
        var queryItem = await _context.CodeRuleItem
            .Where(a => a.CodeRuleId == query.Id)
            .ToListAsync();

        //编辑数据
        var codeRule = _mapper.Map(codeRuleUpdateDTO, query);
        var codeRuleItem = _mapper.Map<List<CodeRuleItemModel>>(codeRuleUpdateDTO.Items);

        //处理子单数据
        foreach (var item in codeRuleItem)
        {
            item.Id = Guid.NewGuid();
            item.CodeRuleId = codeRule.Id;
            if (item.CurrentSerialNumber == null) item.CurrentSerialNumber = 0;
        }

        //更新表
        _context.CodeRuleItem.RemoveRange(queryItem);
        await _context.SaveChangesAsync();

        _context.CodeRule.Update(codeRule);
        _context.CodeRuleItem.AddRange(codeRuleItem);
        await _context.SaveChangesAsync();

        return RequestResponse.OK(codeRuleUpdateDTO.Id);
    }

    #endregion

    #region 删除编码规则

    public async Task<RequestResponseModel> DeleteCodeRule(SingleIdDTO deleteDTO)
    {
        //处理主单
        var query = await Valid.ValidId(_context.CodeRule, deleteDTO.Id);
        if (query == null) return RequestResponse.ErrorRequest("编码规则Id无效");

        //处理子单
        var queryItem = await _context.CodeRuleItem
            .Where(a => a.CodeRuleId == query.Id)
            .ToListAsync();

        //删除操作
        _context.CodeRule.Remove(query);
        _context.CodeRuleItem.RemoveRange(queryItem);

        //保存库
        await _context.SaveChangesAsync();
        return RequestResponse.OK(deleteDTO.Id, "删除成功");
    }

    #endregion

    #region 获取编码规则详情

    public async Task<RequestResponseModel> GetCodeRuleDetail(SingleIdDTO singleIdDTO)
    {
        //查询主单
        var codeRuleDetail = await _context.CodeRule
            .ProjectTo<CodeRuleDetailView>(_mapper.ConfigurationProvider)
            .AsNoTracking().FirstOrDefaultAsync(a => a.Id == singleIdDTO.Id);

        return RequestResponse.OK(codeRuleDetail, "查询成功");
    }

    #endregion

    #region 批量删除编码规则

    public async Task<RequestResponseModel> DeleteArrayCodeRule(IdArrayDTO idArrayDTO)
    {
        //处理主单
        var query = await _context.CodeRule
            .WhereIF(a => idArrayDTO.Ids.Contains(a.Id.ToString()), idArrayDTO != null)
            .ToListAsync();

        if (query.Count != idArrayDTO.Ids.Count) return RequestResponse.ErrorRequest("编码规则Id无效");

        //删除操作
        _context.CodeRule.RemoveRange(query);

        //保存库
        await _context.SaveChangesAsync();
        return RequestResponse.OK(idArrayDTO.Ids, "删除成功");
    }

    #endregion

    #region 获取编码

    public async Task<RequestResponseModel> GetNewCode(string Id)
    {
        //校验数据
        var query = await Valid.ValidId(_context.CodeRule, Id);
        if (query == null) return RequestResponse.ErrorRequest("Id无效", Id);

        //校验子单
        var codeRuleItem = await _context.CodeRuleItem
            .Where(a => a.CodeRuleId.ToString() == Id)
            .OrderBy(a => a.Order)
            .ToListAsync();

        if (codeRuleItem == null || codeRuleItem.Count() == 0) return RequestResponse.ErrorRequest("编码规则没有相应规则数据", Id);

        //生成规则数据
        var code = "";

        foreach (var item in codeRuleItem)
        {
            if (item.CodeType == SystemCoreEnum.CodeTypeEnum.常量)
            {
                //增加常量
                code += item.Constant;
            }
            else if (item.CodeType == SystemCoreEnum.CodeTypeEnum.时间)
            {
                //判断时间
                if (item.DateType == SystemCoreEnum.DateTypeEnum.年月)
                    code += DateTime.Now.ToString("yyyyMM");
                else if (item.DateType == SystemCoreEnum.DateTypeEnum.年月日)
                    code += DateTime.Now.ToString("yyyyMMdd");
                else if (item.DateType == SystemCoreEnum.DateTypeEnum.月日)
                    code += DateTime.Now.ToString("MMdd");
                else if (item.DateType == SystemCoreEnum.DateTypeEnum.年) code += DateTime.Now.ToString("yyyy");
            }
            else if (item.CodeType == SystemCoreEnum.CodeTypeEnum.流水号)
            {
                //增加流水号
                if (item.CurrentSerialNumber == null)
                {
                    //第一次调用
                    item.CurrentSerialNumber = item.InitSerialNumber;
                    item.LastRefreshTime = DateTime.Now;
                }
                else
                {
                    if (item.SerialRefreshDateType == SystemCoreEnum.RefreshDateTypeEnum.年)
                    {
                        //刷新时间为年
                        if (DateTime.Now.Year != item.LastRefreshTime.Value.Year)
                            //不为当年则刷新
                            item.CurrentSerialNumber = item.InitSerialNumber;
                        else
                            //为当年则叠加
                            item.CurrentSerialNumber++;
                        item.LastRefreshTime = DateTime.Now;
                    }
                    else if (item.SerialRefreshDateType == SystemCoreEnum.RefreshDateTypeEnum.月)
                    {
                        //刷新时间为月
                        if (DateTime.Now.Month != item.LastRefreshTime.Value.Month)
                            //不为当月则刷新
                            item.CurrentSerialNumber = item.InitSerialNumber;
                        else
                            //为当月则叠加
                            item.CurrentSerialNumber++;
                        item.LastRefreshTime = DateTime.Now;
                    }
                    else if (item.SerialRefreshDateType == SystemCoreEnum.RefreshDateTypeEnum.日)
                    {
                        //刷新时间为月
                        if (DateTime.Now.Day != item.LastRefreshTime.Value.Day)
                            //不为当日则刷新
                            item.CurrentSerialNumber = item.InitSerialNumber;
                        else
                            //为当日则叠加
                            item.CurrentSerialNumber++;
                        item.LastRefreshTime = DateTime.Now;
                    }
                }

                //格式化流水号
                var serialLength = (item.SerialLength ?? 0) - item.CurrentSerialNumber.ToString().Length;
                if (serialLength <= 0)
                    code += serialLength;
                else
                    code += item.CurrentSerialNumber.ToString().PadLeft(serialLength, '0');
            }

            //增加间隔符号
            if (query.Symbol != null)
                if (codeRuleItem.IndexOf(item) < codeRuleItem.Count() - 1)
                    code += query.Symbol;
        }

        //更新当前编码
        query.CurrentValue = code;

        //更新表
        _context.CodeRule.Update(query);
        await _context.SaveChangesAsync();

        return RequestResponse.OK(code, "获取成功");
    }

    #endregion

    #region 初始化

    //数据库
    private readonly DatabaseContext _context;

    //自动映射
    private readonly IMapper _mapper;

    //构造注入
    public CodeRuleService(DatabaseContext context, IMapper mapper)
    {
        _context = context;
        _mapper = mapper;
    }

    #endregion
}